import requests, urllib, json
from src.utils.deep import get_os_info
from flask import request, Response, make_response, send_file
from src.core.variables.status import SUCCESS_CODE, ERROR_CODE

def download_file(full_url):
    """
    文件下载API代理
    保持与原接口相同的请求/响应结构
    @param: full_url 目标服务地址
    """
    try:
        # 转发请求到原始服务
        resp = requests.request(
            method=request.method,
            url=full_url,
            headers={key: value for (key, value) in request.headers if key != 'Host'},
            data=request.get_data(),
            cookies=request.cookies,
            allow_redirects=False,
            stream=True  # 保持流式传输
        )

        # 构造代理响应
        proxy_response = make_response(
            send_file(
                resp.raw,
                as_attachment=True,
                download_name=resp.headers.get('Content-Disposition', '').split('filename=')[-1].strip('"'),
                conditional=True,
            )
        )

        # 复制原始响应头
        for header, value in resp.headers.items():
            if header.lower() not in ['content-encoding', 'content-length', 'transfer-encoding']:
                proxy_response.headers[header] = value

        # 确保文件名编码正确
        if 'Content-Disposition' in resp.headers:
            filename = resp.headers['Content-Disposition'].split('filename=')[-1].strip('"')
            encoded_filename = urllib.parse.quote(filename.encode('utf-8'))
            proxy_response.headers["Content-Disposition"] = f"attachment; filename*=UTF-8''{encoded_filename}"

        # 禁用缓存
        proxy_response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate"
        proxy_response.headers["Pragma"] = "no-cache"
        proxy_response.headers["Expires"] = "0"

        return proxy_response

    except requests.exceptions.RequestException as e:
        return ERROR_CODE.PROXY_REQUEST_ERROR(e)


def log_sse(full_url):
    """
    SSE日志流API代理
    保持与原接口相同的流式响应结构
    @param: full_url 目标服务地址
    """
    try:
        # 转发请求到原始服务
        resp = requests.request(
            method=request.method,
            url=full_url,
            headers={key: value for (key, value) in request.headers if key != 'Host'},
            data=request.get_data(),
            cookies=request.cookies,
            allow_redirects=False,
            stream=True  # 保持流式传输
        )

        # 流式响应生成器
        def generate():
            for chunk in resp.iter_content(chunk_size=None):
                if chunk:
                    yield chunk

        # 构造代理响应
        proxy_response = Response(
            generate(),
            content_type=resp.headers.get('Content-Type', 'text/event-stream'),
            status=resp.status_code
        )

        # 复制必要的响应头
        for header in ['Cache-Control', 'Connection', 'X-Accel-Buffering']:
            if header in resp.headers:
                proxy_response.headers[header] = resp.headers[header]

        return proxy_response

    except requests.exceptions.RequestException as e:
        # 对于SSE连接错误，返回JSON格式错误信息
        error_data = json.dumps({
            "status_code": 'error',
            "message": f"SSE代理连接失败: {str(e)}",
            "time": get_os_info.local_time("no week"),
            "sse_id": "proxy-error",
            "app_id": request.args.get('app_id', 'unknown')
        })
        return Response(f"data: {error_data}\n\n", content_type='text/event-stream')


def receive_file(full_url):
    """
    文件接收API代理转发
    @param: full_url 目标服务地址
    """
    try:
        # 获取上传的文件
        file = request.files.get("file")
        if not file or file.content_type is None:
            return {"error": "未上传文件！"}, 400

        # 准备转发请求l
        files = {'file': (file.filename, file.stream, file.content_type)}
        headers = {key: value for (key, value) in request.headers if key.lower() != 'host'}
        
        # 转发到原始服务
        resp = requests.post(
            url=full_url,
            files=files,
            headers=headers,
            cookies=request.cookies,
            data=request.form  # 传递其他表单数据
        )

        # 返回原始服务的响应
        try:
            response_data = resp.json()
            return response_data, resp.status_code
        except ValueError:
            return resp.content, resp.status_code

    except requests.exceptions.RequestException as e:
        return ERROR_CODE.PROXY_REQUEST_ERROR(e)